home *** CD-ROM | disk | FTP | other *** search
- Subject: v08i066: The VN news reader, Part03/03
- Newsgroups: mod.sources
- Approved: mirror!rs
-
- Submitted by: rtech!rtech!bobm (Bob Mcqueer)
- Mod.sources: Volume 8, Issue 66
- Archive-name: vn/Part03
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
- # If all goes well, you will see the message "End of archive 3 (of 3)."
- # Contents: vn.c vn.man
- # Wrapped by rs@mirror on Tue Feb 17 12:10:41 1987
- PATH=/bin:/usr/bin:/usr/ucb; export PATH
- echo shar: extracting "'vn.c'" '(25993 characters)'
- if test -f 'vn.c' ; then
- echo shar: will not over-write existing file "'vn.c'"
- else
- sed 's/^X//' >vn.c <<'@//E*O*F vn.c//'
- X/*
- Xvn news reader for visual page oriented display of news
- Xaimed at scanning large numbers of articles.
- X
- XOriginal program by Bob McQueer in several versions 1983-1986. Released
- Xinto the public domain in 1986. While no copyright notice appears, the
- Xoriginal author asks that a history of changes crediting the proper people
- Xbe maintained.
- X
- XBob McQueer
- X{amdahl, sun, mtxinu, hoptoad, cpsc6a}!rtech!bobm
- X
- XHistory:
- X
- X (bobm@rtech) 5/86 - first "public" version
- X
- X (bobm@rtech) 12/86 - version incorporates:
- X
- X bug fixes:
- X str_store NULL string bug
- X not picking up first article in newsgroup
- X RESTART terminal reset for exit to editor.
- X skip whitespace in "empty" digest lines while unpacking
- X DISTRIBUTION line in followups.
- X :100%: prompt on last line in reader.
- X interpretation of multiple negations -w -t options.
- X
- X Many thanks to several people who noted the first
- X two bugs as well as fixes.
- X
- X Thank you to Karl Williamson for helpful information
- X tracking down the "concept terminal" bug (RESTART).
- X
- X SYSV ifdef's adapted from those done by Larry Tepper
- X at ATT Denver - sent in by Karl Williamson, drutx!khw.
- X Many people submitted SYSV ifdef's - thank you all.
- X
- X print capability from reader from Karl Williamson,
- X drutx!khw
- X
- X Changes to use alternate header lines for mail, from changes
- X by Andy Marrinson, andy@icom.UUCP (ihnp4!icom!andy). Ifdef'ed
- X to allow local configuration (bobm@rtech).
- X
- X "author_copy" file for followups, prevention of multiple
- X "re: "'s, insert blank line and original author line
- X before excerpted text from Andy Marrinson, andy@icom.UUCP
- X
- X Search string capability in reader, from Lawrie Brown,
- X seismo!munnari!cdsadfa.oz!lpb (Australia). Somewhat
- X modified by interaction with the :100%: bug.
- X
- X Arrow key support, adapted from changes by Lawrie Brown.
- X Modified to simply not allow control keys for arrows (allowing
- X SOME controls is too prone to problems, esp. with .vnkey), and
- X to allow the PAGEARROW ifdef (bobm@rtech)
- X
- X prevention of followups to "mod" and "announce", from
- X Lawrie Brown.
- X
- X OLDRC ifdef adapted from changes by Lawrie Brown. ADDRMUNGE
- X added to allow OZ domain addressing changes from Australia
- X to be grafted back in, and provide a hook for anybody else
- X wanting to do something similar.
- X
- X Bob McQueer, bobm@rtech:
- X
- X a menu selection from the % command to jump to
- X a new newsgroup
- X
- X linked list on hash table - no longer a compiled
- X in limit for number of newsgroups
- X
- X .vnkey keystroke mapping file.
- X
- X options to get the % command list on entry, and to
- X change how unsubscribed groups are handled for updates.
- X
- X allow configurable use of vs / ve pair for terminal
- X handling.
- X
- XKnown bugs:
- X
- X non-erasure of stuff on prompt line when the new
- X string includes an escape sequence (like PS1 maybe)
- X because it doesn't realize that the escape sequence
- X won't overprint the existing stuff
- X
- X control-w and update on exit may not update pages which have been
- X scanned in funny orders by jumping into the middle of groups
- X
- X inaccurate numbers on '%' command results - reflect ranges, not
- X actual numbers of articles.
- X
- X no arrow keys recognized which don't begin with <escape>
- X
- X doesn't know about the version 2.11 'm' in active list, or
- X use the 'y' / 'n' either.
- X
- X crash due to embedding $\(\) type substring specifiers in regular
- X expressions. Obscure and hard to fix in a proper and portable way.
- X*/
- X#include <stdio.h>
- X#include <setjmp.h>
- X#include "config.h"
- X#include "tty.h"
- X#include "vn.h"
- X
- X/* UNIX error number */
- Xextern int errno;
- X
- Xextern NODE **Newsorder;
- Xextern char Erasekey, Killkey;
- Xextern int Rot;
- Xextern char *Ps1,*Printer;
- Xextern char *Orgdir,*Savefile,*Savedir;
- Xextern int Ncount, Cur_page, Lrec, L_allow, C_allow;
- Xextern int Headflag;
- Xextern PAGE Page;
- Xextern int Digest;
- Xextern char *No_msg;
- Xextern char *Hdon_msg;
- Xextern char *Hdoff_msg;
- Xextern char *Roton_msg;
- Xextern char *Rotoff_msg;
- Xextern char Cxitop[], Cxptoi[];
- X
- Xextern char *Aformat;
- X
- Xextern char *Contstr;
- X
- Xextern char *Kl,*Kr,*Ku,*Kd;
- X
- Xextern int Nounsub, Listfirst;
- X
- Xstatic int C_info;
- Xstatic int Dskip, Drec;
- X
- Xstatic char *Unsub_msg = "Unsubscribed";
- Xstatic char *Egroup_msg = "Entire newsgroup";
- X
- X/*
- X Help message table. Character for command, plus its help
- X message. Table order is order of presentation to user.
- X*/
- Xstatic struct HELPTAB
- X{
- X char cmd, *msg;
- X int dig;
- X char *amsg;
- X}
- XHelptab [] =
- X{
- X { QUIT, "quit", 1, NULL},
- X { UP, "(or up arrow) move up [number of lines]", 1, NULL},
- X { DOWN, "(or down arrow) move down [number of lines]", 1, NULL},
- X#ifdef PAGEARROW
- X { BACK, "(or left arrow) previous page [number of pages]", 1, NULL},
- X { FORWARD, "(or right arrow) next page [number of pages]", 1, NULL},
- X#else
- X { BACK, "previous page [number of pages]", 1, NULL},
- X { FORWARD, "next page [number of pages]", 1, NULL},
- X#endif
- X { DIGEST, "unpack digest", 1, "exit digest"},
- X { READ, "read article [number of articles]", 1, NULL},
- X { ALTREAD, "read article (alternate 'r')", 1, NULL},
- X { READALL, "read all articles on page", 1, NULL},
- X { READSTRING, "specify articles to read", 1, NULL},
- X { SAVE, "save or pipe article [number of articles]", 1, NULL},
- X { SAVEALL, "save or pipe all articles on page", 1, NULL},
- X { SAVESTRING, "specify articles to save", 1, NULL},
- X { ALTSAVE, "specify articles to save (alternate ctl-s)", 1, NULL},
- X { PRINT, "print article [number of articles]", 1, NULL},
- X { PRINTALL, "print all article on page", 1, NULL},
- X { PRINTSTRING, "specify articles to print", 1, NULL},
- X { UPDATE, "update .newsrc status to cursor", 0, NULL},
- X { UPALL, "update .newsrc status for whole newsgroup", 0, NULL},
- X { UPSEEN, "update .newsrc status for all pages displayed", 0, NULL},
- X { ORGGRP, "recover original .newsrc status for newsgroup", 0, NULL},
- X { ORGSTAT, "recover all original .newsrc status", 0, NULL},
- X { SSTAT, "display count of groups and pages - shown and total", 0, NULL},
- X { GRPLIST, "list newsgroups with new article, updated counts", 0, NULL},
- X { NEWGROUP, "specify newsgroup to display and/or resubscribe to", 1, NULL},
- X { UNSUBSCRIBE, "unsubscribe from group", 0, NULL},
- X { MARK, "mark/unmark article [number of articles]", 1, NULL},
- X { ART_MARK, "mark/unmark article [number of articles]", 1, NULL},
- X { UNMARK, "erase marks on articles", 1, NULL},
- X { HEADTOG, "toggle flag for display of headers when reading", 1, NULL},
- X { SETROT, "toggle rotation for reading", 1, NULL},
- X { REDRAW, "redraw screen", 1, NULL},
- X { UNESC, "escape to UNIX to execute a command", 1, NULL},
- X { HELP, "show this help menu", 1, NULL}
- X};
- X
- Xmain(argc,argv)
- Xint argc;
- Xchar **argv;
- X{
- X /*
- X initialize environment variables,
- X scan .newsrc file, using any command line options present.
- X */
- X term_set (START);
- X envir_set ();
- X sig_set (BRK_IN);
- X
- X scan_newsrc (argc-1,argv+1);
- X tty_set (BACKSTOP);
- X
- X if (Lrec >= 0)
- X session ();
- X else
- X {
- X new_groups ();
- X fprintf (stderr,"\nNo News\n");
- X }
- X
- X tty_set (COOKED);
- X wr_newsrc ();
- X term_set (STOP);
- X}
- X
- X/*
- X main session handler processing input commands
- X locals:
- X count - count attached to command
- X highrec - highest line on current page
- X crec - current line
- X
- X NOTE: this is where a setjmp call is made to set the break reentry
- X location. Keep the possible user states in mind.
- X*/
- Xsession ()
- X{
- X char alist [RECLEN], c;
- X int newg, i, j, count, highrec, crec;
- X jmp_buf brkbuf;
- X
- X tty_set (RAWMODE);
- X newg = new_groups();
- X find_page (0);
- X Digest = 0;
- X
- X /* reentry point for break from within session interaction */
- X setjmp (brkbuf);
- X sig_set (BRK_SESS,brkbuf);
- X Headflag = FALSE;
- X Rot = 0;
- X
- X /* done this way so that user gets "really quit?" break treatment */
- X if (newg > 0)
- X {
- X printf ("\n%s",Contstr);
- X getnoctl();
- X newg = 0;
- X }
- X
- X /* list preview option - clear after first time for long jumps */
- X if (Listfirst)
- X {
- X /* tot_list settings will be overwritten in this case */
- X tot_list(&crec,&highrec);
- X Listfirst = 0;
- X }
- X
- X /* if breaking from a digest, recover original page */
- X if (Digest)
- X {
- X find_page(Cur_page);
- X Digest = 0;
- X }
- X show ();
- X crec = RECBIAS;
- X highrec = Page.h.artnum + RECBIAS;
- X term_set (MOVE,0,crec);
- X
- X /*
- X handle commands until QUIT, update global/local status
- X and display for each.
- X */
- X for (count = getkey(&c); c != QUIT; count = getkey(&c))
- X {
- X for (i=0; i < (j = sizeof(Helptab)/sizeof(struct HELPTAB)); ++i)
- X if (Helptab[i].cmd == c)
- X break;
- X
- X if (i >= j || (Digest && !Helptab[i].dig))
- X {
- X preinfo (UDKFORM,Cxptoi[HELP]);
- X term_set (MOVE, 0, crec);
- X continue;
- X }
- X
- X switch (c)
- X {
- X case HEADTOG:
- X if (Headflag)
- X {
- X Headflag = FALSE;
- X prinfo (Hdoff_msg);
- X }
- X else
- X {
- X Headflag = TRUE;
- X prinfo (Hdon_msg);
- X }
- X term_set (MOVE,0,crec);
- X break;
- X case SETROT:
- X if (Rot == 0)
- X {
- X Rot = 13;
- X prinfo (Roton_msg);
- X }
- X else
- X {
- X Rot = 0;
- X prinfo (Rotoff_msg);
- X }
- X term_set (MOVE,0,crec);
- X break;
- X case SSTAT:
- X count_msg ();
- X term_set (MOVE,0,crec);
- X break;
- X case GRPLIST:
- X tot_list (&crec,&highrec);
- X show();
- X term_set (MOVE,0,crec);
- X break;
- X case REDRAW:
- X show();
- X term_set (MOVE,0,crec);
- X break;
- X case UNSUBSCRIBE:
- X (Page.h.group)->state &= ~FLG_SUB;
- X wr_newsrc ();
- X prinfo (Unsub_msg);
- X term_set (MOVE,0,crec);
- X break;
- X
- X case UPDATE:
- X (Page.h.group)->rdnum = Page.b[crec-RECBIAS].art_id;
- X wr_show ();
- X wr_newsrc();
- X term_set (MOVE,0,crec);
- X break;
- X case UPALL:
- X (Page.h.group)->rdnum = (Page.h.group)->art;
- X wr_newsrc();
- X wr_show();
- X prinfo (Egroup_msg);
- X term_set (MOVE,0,crec);
- X break;
- X case ORGGRP:
- X (Page.h.group)->rdnum = (Page.h.group)->orgrd;
- X wr_newsrc();
- X wr_show();
- X prinfo (Egroup_msg);
- X term_set (MOVE,0,crec);
- X break;
- X case UPSEEN:
- X up_seen();
- X prinfo ("All pages displayed to this point updated");
- X wr_show();
- X wr_newsrc();
- X term_set (MOVE,0,crec);
- X break;
- X case ORGSTAT:
- X for (i = 0; i < Ncount; ++i)
- X (Newsorder[i])->rdnum = (Newsorder[i])->orgrd;
- X prinfo ("Original data recovered");
- X wr_show();
- X wr_newsrc();
- X term_set (MOVE,0,crec);
- X break;
- X case UP:
- X if (crec != RECBIAS)
- X {
- X crec -= count;
- X if (crec < RECBIAS)
- X crec = RECBIAS;
- X term_set (MOVE, 0, crec);
- X }
- X else
- X putchar ('\07');
- X break;
- X case DOWN:
- X if (crec < (highrec - 1))
- X {
- X crec += count;
- X if (crec >= highrec)
- X crec = highrec - 1;
- X term_set (MOVE, 0, crec);
- X }
- X else
- X putchar ('\07');
- X break;
- X case MARK:
- X case ART_MARK:
- X count += crec - 1;
- X if (count >= highrec)
- X count = highrec - 1;
- X for (i=crec; i <= count; ++i)
- X {
- X if (Page.b[i-RECBIAS].art_mark != ART_MARK)
- X Page.b[i-RECBIAS].art_mark = ART_MARK;
- X else
- X Page.b[i-RECBIAS].art_mark = ' ';
- X if (i != crec)
- X term_set (MOVE, 0, i);
- X printf ("%c\010",Page.b[i-RECBIAS].art_mark);
- X }
- X if (count != crec)
- X term_set (MOVE, 0, crec);
- X write_page ();
- X break;
- X case UNMARK:
- X for (i=0; i < Page.h.artnum; ++i)
- X {
- X if (Page.b[i].art_mark == ART_MARK)
- X {
- X Page.b[i].art_mark = ' ';
- X term_set (MOVE, 0, i+RECBIAS);
- X putchar (' ');
- X }
- X }
- X term_set (MOVE, 0, crec);
- X write_page ();
- X break;
- X case BACK:
- X count *= -1; /* fall through */
- X case FORWARD:
- X if (forward (count, &crec, &highrec) >= 0)
- X show();
- X else
- X preinfo ("No more pages");
- X term_set (MOVE,0,crec);
- X break;
- X case DIGEST:
- X if (Digest)
- X {
- X Digest = 0;
- X find_page (Cur_page);
- X show();
- X crec = Drec + RECBIAS + 1;
- X highrec = Page.h.artnum + RECBIAS;
- X if (crec >= highrec)
- X crec = highrec - 1;
- X term_set (MOVE,0,crec);
- X break;
- X }
- X Dskip = count - 1;
- X Drec = crec - RECBIAS;
- X if (digest_page(Drec,Dskip) >= 0)
- X {
- X show();
- X crec = RECBIAS;
- X highrec = Page.h.artnum + RECBIAS;
- X term_set (MOVE,0,crec);
- X break;
- X }
- X Digest = 0;
- X preinfo ("Can't unpack the article");
- X term_set (MOVE,0,crec);
- X break;
- X case NEWGROUP:
- X if ((i = spec_group()) < 0)
- X {
- X term_set (MOVE,0,crec);
- X break;
- X }
- X Digest = 0;
- X show();
- X crec = RECBIAS;
- X highrec = Page.h.artnum + RECBIAS;
- X term_set (MOVE,0,crec);
- X break;
- X
- X case SAVE:
- X genlist (alist,crec-RECBIAS,count);
- X savestr (alist);
- X term_set (MOVE,0,crec);
- X break;
- X case SAVEALL:
- X genlist (alist,0,L_allow);
- X savestr (alist);
- X term_set (MOVE,0,crec);
- X break;
- X case SAVESTRING:
- X case ALTSAVE:
- X userlist (alist);
- X savestr (alist);
- X term_set (MOVE,0,crec);
- X break;
- X case READ:
- X case ALTREAD:
- X genlist (alist,crec-RECBIAS,count);
- X readstr (alist,&crec,&highrec,count);
- X break;
- X case READALL:
- X genlist (alist,0,L_allow);
- X readstr (alist,&crec,&highrec,0);
- X break;
- X case READSTRING:
- X userlist (alist);
- X readstr (alist,&crec,&highrec,0);
- X break;
- X case PRINT:
- X genlist (alist,crec-RECBIAS,count);
- X printstr (alist);
- X term_set (MOVE,0,crec);
- X break;
- X case PRINTALL:
- X genlist (alist,0,L_allow);
- X printstr (alist);
- X term_set (MOVE, 0, crec);
- X break;
- X case PRINTSTRING:
- X userlist (alist);
- X printstr (alist);
- X term_set (MOVE, 0, crec);
- X break;
- X
- X case HELP:
- X help ();
- X show ();
- X term_set (MOVE, 0, crec);
- X break;
- X case UNESC:
- X user_str (alist,Ps1,1);
- X term_set (ERASE);
- X fflush (stdout);
- X tty_set (SAVEMODE);
- X if (chdir(Orgdir) < 0)
- X printf ("change to original directory, %s, failed",Orgdir);
- X else
- X {
- X system (alist);
- X tty_set (RESTORE);
- X term_set (RESTART);
- X }
- X printf (Contstr);
- X getnoctl ();
- X cd_group ();
- X show ();
- X term_set (MOVE, 0, crec);
- X break;
- X default:
- X printex ("Unhandled key: %c", c);
- X break;
- X }
- X }
- X
- X Digest = 0;
- X for (i=0; i < Ncount; ++i)
- X {
- X if ((Newsorder[i])->rdnum < (Newsorder[i])->pgrd)
- X break;
- X }
- X if (i < Ncount)
- X {
- X user_str (alist,"Some displayed pages not updated - update ? ",1);
- X if (alist[0] == 'y')
- X up_seen();
- X }
- X sig_set (BRK_OUT);
- X}
- X
- X/*
- X** update status of Newsgroups to all seen pages
- X*/
- Xup_seen()
- X{
- X int i;
- X
- X for (i = 0; i < Ncount; ++i)
- X {
- X if (Nounsub && ((Newsorder[i])->state & FLG_SUB) == 0)
- X {
- X (Newsorder[i])->rdnum = (Newsorder[i])->art;
- X continue;
- X }
- X if ((Newsorder[i])->rdnum < (Newsorder[i])->pgrd)
- X (Newsorder[i])->rdnum = (Newsorder[i])->pgrd;
- X }
- X}
- X
- X/*
- X count_msg displays count information
- X*/
- Xcount_msg ()
- X{
- X int i, gpnum, gscan, gpage;
- X unsigned long mask;
- X gpnum = 1;
- X for (gscan = gpage = i = 0; i<Ncount; ++i)
- X {
- X if (((Newsorder[i])->state & FLG_PAGE) != 0)
- X {
- X if (((Newsorder[i])->pnum + (Newsorder[i])->pages - 1) < Cur_page)
- X ++gpnum;
- X ++gpage;
- X for (mask=1; mask != 0L; mask <<= 1)
- X if (((Newsorder[i])->pgshwn & mask) != 0L)
- X ++gscan;
- X }
- X }
- X prinfo (CFORMAT,Cur_page+1,Lrec+1,gscan,gpnum,gpage);
- X}
- X
- X/*
- X forward utility handles paging to allow it to happen globally.
- X (from readstr, for instance)
- X*/
- Xforward (count, crec, highrec)
- Xint count, *crec, *highrec;
- X{
- X if (!Digest)
- X {
- X if ((count < 0 && Cur_page <= 0) || (count > 0 && Cur_page >= Lrec))
- X return (-1);
- X Cur_page += count;
- X if (Cur_page < 0)
- X Cur_page = 0;
- X if (Cur_page > Lrec)
- X Cur_page = Lrec;
- X find_page (Cur_page);
- X *crec = RECBIAS;
- X *highrec = Page.h.artnum + RECBIAS;
- X return (0);
- X }
- X /*
- X ** in digests, paging past the end of the digest returns to
- X ** page extracted from.
- X */
- X if (Dskip > 0 && (Dskip + count*L_allow) < 0)
- X Dskip = 0;
- X else
- X Dskip += count * L_allow;
- X find_page (Cur_page);
- X if (Dskip >= 0)
- X {
- X if (digest_page(Drec,Dskip) >= 0)
- X {
- X *crec = RECBIAS;
- X *highrec = Page.h.artnum + RECBIAS;
- X return (0);
- X }
- X }
- X Digest = 0;
- X *crec = Drec + RECBIAS + 1;
- X *highrec = Page.h.artnum + RECBIAS;
- X if (*crec >= *highrec)
- X *crec = *highrec - 1;
- X return (0);
- X}
- X
- X/*
- X error/abnormal condition cleanup and abort routine
- X pass stack to printf
- X*/
- Xprintex (s,a,b,c,d,e,f)
- Xchar *s;
- Xlong a,b,c,d,e,f;
- X{
- X static int topflag=0;
- X if (topflag == 0)
- X {
- X ++topflag;
- X term_set (STOP);
- X tty_set (COOKED);
- X fflush (stdout);
- X fprintf (stderr,s,a,b,c,d,e,f);
- X fprintf (stderr," (error code %d)\n",errno);
- X exit (1);
- X }
- X else
- X fprintf (stderr,s,a,b,c,d,e,f);
- X}
- X
- X/*
- X getkey obtains user keystroke with count from leading
- X numerics, if any. Picks up arrow key sequences and maps
- X them to other keys. Also translates character through
- X Cxitop array since this routine is only used in session
- X loop. Saves untranslating arrow keys.
- X*/
- Xgetkey (c)
- Xchar *c;
- X{
- X int i, j;
- X static char ckseq[32];
- X
- X /* Check for leading count */
- X for (i = 0; (*c = getchar() & 0x7f) >= '0' && *c <= '9'; i = i * 10 + *c - '0')
- X ;
- X
- X /* @#$!!! flakey front ends that won't map newlines in raw mode */
- X if (*c == '\012' || *c == '\015')
- X *c = '\n';
- X
- X /* @#$!!! flakey terminals which send control sequences for cursors! */
- X if( *c == '\033' )
- X {
- X /*
- X ** Check if part of cursor key input sequence
- X ** (pitch unknown escape sequences)
- X */
- X j = 0;
- X ckseq[j] = *c; ckseq[j+1] = '\0';
- X while(*c == Ku[j] || *c == Kd[j] || *c == Kl[j] || *c == Kr[j])
- X {
- X if( strcmp(ckseq, Ku) == 0 ) { *c = UP; break; }
- X if( strcmp(ckseq, Kd) == 0 ) { *c = DOWN; break; }
- X#ifdef PAGEARROW
- X if( strcmp(ckseq, Kl) == 0 ) { *c = BACK; break; }
- X if( strcmp(ckseq, Kr) == 0 ) { *c = FORWARD; break; }
- X#else
- X if( strcmp(ckseq, Kl) == 0 ) { *c = UP; break; }
- X if( strcmp(ckseq, Kr) == 0 ) { *c = DOWN; break; }
- X#endif
- X *c = (getchar() & 0x7f);
- X ckseq[++j] = *c; ckseq[j+1] = '\0';
- X }
- X }
- X else
- X *c = Cxitop[*c];
- X
- X if (i <= 0)
- X i = 1;
- X return (i);
- X}
- X
- X
- X/*
- X get user key ignoring most controls
- X*/
- Xgetnoctl ()
- X{
- X char c;
- X while ((c = getchar() & 0x7f) < ' ' || c == '\177')
- X {
- X if (c == '\015' || c == '\012')
- X c = '\n';
- X if (c == '\n' || c == '\b' || c == '\t')
- X return (c);
- X }
- X return ((int) c);
- X}
- X
- X/*
- X generate list of articles on current page,
- X count articles, starting with first.
- X*/
- Xgenlist (list,first,count)
- Xchar *list;
- Xint first,count;
- X{
- X int i;
- X for (i=first; i < Page.h.artnum && count > 0; ++i)
- X {
- X sprintf (list,"%d ",Page.b[i].art_id);
- X list += strlen(list);
- X --count;
- X }
- X}
- X
- X/*
- X send list of articles to printer
- X*/
- Xprintstr (s)
- Xchar *s;
- X{
- X char *ptr, cmd [RECLEN], *strpbrk();
- X prinfo ("preparing print command ....");
- X for (ptr = s; (ptr = strpbrk(ptr, LIST_SEP)) != NULL; ++ptr)
- X *ptr = ' ';
- X while (*s == ' ')
- X ++s;
- X if (Digest)
- X dig_list (s);
- X if (*s != '\0')
- X {
- X sprintf (cmd,"%s %s 2>/dev/null",Printer,s);
- X if (system (cmd) == 0)
- X prinfo ("Sent to printer");
- X else
- X preinfo ("Print failed");
- X }
- X else
- X preinfo (No_msg);
- X if (Digest)
- X dig_ulist (s);
- X}
- X
- X/*
- X concatenate articles to save file with appropriate infoline messages.
- X prompt for save file, giving default. If save file begins with "|"
- X handle as a filter to pipe to. NOTE - every user specification of
- X a new Savefile "loses" some storage, but it shouldn't be a very great
- X amount.
- X*/
- Xsavestr (s)
- Xchar *s;
- X{
- X char *ptr, cmd [RECLEN], newfile [MAX_C+1], prompt[MAX_C];
- X char *strtok(), *strpbrk(), *str_store();
- X
- X for (ptr = s; (ptr = strpbrk(ptr, LIST_SEP)) != NULL; ++ptr)
- X *ptr = ' ';
- X while (*s == ' ')
- X ++s;
- X if (Digest)
- X dig_list (s);
- X if (*s != '\0')
- X {
- X sprintf (prompt,SAVFORM,Savefile);
- X user_str (newfile,prompt,1);
- X ptr = newfile;
- X if (*ptr == '|')
- X {
- X sprintf(cmd,"cat %s %s",s,ptr);
- X term_set (ERASE);
- X fflush (stdout);
- X tty_set (SAVEMODE);
- X system (cmd);
- X tty_set (RESTORE);
- X printf (Contstr);
- X getnoctl ();
- X show ();
- X }
- X else
- X {
- X prinfo ("saving .... ");
- X if (*ptr == '\0')
- X ptr = Savefile;
- X else
- X Savefile = str_store(ptr);
- X if (*ptr != '/' && *ptr != '$')
- X sprintf(cmd,"cat %s >>%s/%s 2>/dev/null",s,Savedir,ptr);
- X else
- X sprintf(cmd,"cat %s >>%s 2>/dev/null",s,ptr);
- X if (system (cmd) == 0)
- X prinfo ("Saved");
- X else
- X preinfo ("Could not append save file");
- X }
- X }
- X else
- X preinfo (No_msg);
- X if (Digest)
- X dig_ulist (s);
- X}
- X
- X/*
- X basic page display routine. erase screen and format current page
- X*/
- Xshow ()
- X{
- X int i;
- X unsigned long mask;
- X char helpstr[40];
- X
- X term_set (ERASE);
- X C_info = 0;
- X i = Cur_page - (Page.h.group)->pnum + 1;
- X if (Digest)
- X printf (DHFORMAT,Page.h.name);
- X else
- X printf (HFORMAT,Page.h.name,i,(Page.h.group)->pages);
- X
- X mask = 1L << (i-1);
- X (Page.h.group)->pgshwn |= mask;
- X mask = 1;
- X for (--i; i > 0 && (mask & (Page.h.group)->pgshwn) != 0 ; --i)
- X mask <<= 1;
- X if (i <= 0)
- X (Page.h.group)->pgrd = Page.b[(Page.h.artnum)-1].art_id;
- X
- X for (i=0; i < Page.h.artnum; ++i)
- X {
- X if (Digest)
- X {
- X printf(Aformat,Page.b[i].art_mark,ART_UNWRITTEN,Page.b[i].art_id);
- X printf("%s",Page.b[i].art_t);
- X continue;
- X }
- X
- X if ((Page.h.group)->rdnum >= Page.b[i].art_id)
- X printf(Aformat,Page.b[i].art_mark,ART_WRITTEN,Page.b[i].art_id);
- X else
- X printf(Aformat,Page.b[i].art_mark,ART_UNWRITTEN,Page.b[i].art_id);
- X printf("%s",Page.b[i].art_t);
- X }
- X
- X sprintf(helpstr,HELPFORM,Cxptoi[HELP]);
- X if (!Digest && ((Page.h.group)->state & FLG_SUB) == 0)
- X prinfo ("%s, %s",Unsub_msg,helpstr);
- X else
- X prinfo (helpstr);
- X}
- X
- X/*
- X update written status marks on screen
- X*/
- Xwr_show ()
- X{
- X int i,row;
- X char c;
- X
- X row = RECBIAS;
- X for (i=0; i < Page.h.artnum; ++i)
- X {
- X term_set (MOVE,WRCOL,row);
- X if ((Page.h.group)->rdnum >= Page.b[i].art_id)
- X c = ART_WRITTEN;
- X else
- X c = ART_UNWRITTEN;
- X printf("%c",c);
- X ++row;
- X }
- X}
- X
- X/*
- X obtain user input of group name, becomes current page if valid.
- X returns -1 or page number. calling routine does the show, if needed
- X*/
- Xspec_group ()
- X{
- X char nbuf [MAX_C + 1];
- X NODE *p, *hashfind();
- X
- X user_str(nbuf,"Newsgroup ? ",1);
- X
- X if (*nbuf == '\0' || (p = hashfind(nbuf)) == NULL)
- X {
- X preinfo ("Not a newsgroup");
- X return (-1);
- X }
- X if ((p->state & FLG_PAGE) == 0)
- X {
- X if ((p->state & FLG_SUB) == 0)
- X {
- X p->state |= FLG_SUB;
- X wr_newsrc ();
- X prinfo ("Not subscribed: resubscribed for next reading session");
- X }
- X else
- X prinfo ("No news for that group");
- X return (-1);
- X }
- X if ((p->state & FLG_SUB) == 0)
- X {
- X p->state |= FLG_SUB;
- X wr_newsrc ();
- X }
- X find_page (p->pnum);
- X return (p->pnum);
- X}
- X
- X/*
- X obtain user input with prompt p. Optionally on info line.
- X handle erase and kill characters, suppresses leading
- X white space.
- X*/
- Xuser_str (s,p,iline)
- Xchar *s;
- Xchar *p;
- Xint iline;
- X{
- X int i,idx;
- X
- X if (iline)
- X {
- X prinfo ("%s",p);
- X idx = C_info;
- X }
- X else
- X {
- X printf ("%s",p);
- X idx = strlen(p);
- X }
- X
- X for (i=0; idx < C_allow && (s[i] = getchar() & 0x7f) != '\012' && s[i] != '\015'; ++i)
- X {
- X if (s[i] == Erasekey)
- X {
- X if (i > 0)
- X {
- X term_set (RUBSEQ);
- X i -= 2;
- X --idx;
- X }
- X continue;
- X }
- X if (s[i] == Killkey)
- X {
- X prinfo ("%s",p);
- X i = -1;
- X continue;
- X }
- X if ((s[i] == ' ' || s[i] == '\t') && i == 0)
- X {
- X i = -1;
- X continue;
- X }
- X ++idx;
- X putchar (s[i]);
- X }
- X
- X if (iline)
- X C_info = idx;
- X
- X s[i] = '\0';
- X}
- X
- X
- X/*
- X print something on the information line,
- X clearing any characters not overprinted.
- X preinfo includes reverse video and a bell for error messages.
- X*/
- Xpreinfo (s,a,b,c,d,e,f)
- X{
- X int l;
- X char buf[RECLEN];
- X
- X term_set (MOVE,0,INFOLINE);
- X putchar ('\07');
- X term_set (ONREVERSE);
- X sprintf (buf,s,a,b,c,d,e,f);
- X printf (" %s ",buf);
- X term_set (OFFREVERSE);
- X l = strlen(buf) + 2;
- X if (l < C_info)
- X term_set (ZAP,l,C_info);
- X C_info = l;
- X fflush(stdout);
- X}
- X
- Xprinfo (s,a,b,c,d,e,f)
- Xchar *s;
- Xlong a,b,c,d,e,f;
- X{
- X int l;
- X char buf[RECLEN];
- X term_set (MOVE,0,INFOLINE);
- X sprintf (buf,s,a,b,c,d,e,f);
- X printf ("%s",buf);
- X l = strlen(buf);
- X if (l < C_info)
- X term_set (ZAP,l,C_info);
- X C_info = l;
- X fflush(stdout);
- X}
- X
- X/*
- X help menu
- X*/
- Xhelp ()
- X{
- X int i,lcount,lim;
- X term_set (ERASE);
- X lim = L_allow + RECBIAS - 2;
- X printf("%s\n",HELP_HEAD);
- X lcount = HHLINES;
- X for (i=0; i < (sizeof(Helptab))/(sizeof(struct HELPTAB)); ++i)
- X {
- X if (Digest && !(Helptab[i].dig))
- X continue;
- X ++lcount;
- X if (Digest && Helptab[i].amsg != NULL)
- X h_print (Cxptoi[Helptab[i].cmd],Helptab[i].amsg);
- X else
- X h_print (Cxptoi[Helptab[i].cmd],Helptab[i].msg);
- X if (lcount >= lim)
- X {
- X printf ("\n%s",Contstr);
- X getnoctl ();
- X term_set (MOVE,0,lim+1);
- X term_set (ZAP,0,strlen(Contstr));
- X term_set (MOVE,0,lim-1);
- X putchar ('\n');
- X lcount = 0;
- X }
- X }
- X if (lcount > 0)
- X {
- X printf ("\n%s",Contstr);
- X getnoctl ();
- X }
- X}
- X
- X/*
- X h_print prints a character and a legend for a help menu.
- X*/
- Xh_print(c,s)
- Xchar c,*s;
- X{
- X if (strlen(s) > (C_allow - 14))
- X s [C_allow - 14] = '\0';
- X if (c > ' ' && c != '\177')
- X printf (" %c - %s\n",c,s);
- X else
- X {
- X switch (c)
- X {
- X case '\177':
- X printf (" <delete> - %s\n",s);
- X break;
- X case '\040':
- X printf (" <space> - %s\n",s);
- X break;
- X case '\033':
- X printf (" <escape> - %s\n",s);
- X break;
- X case '\n':
- X printf (" <return> - %s\n",s);
- X break;
- X case '\t':
- X printf (" <tab> - %s\n",s);
- X break;
- X case '\b':
- X printf (" <back sp> - %s\n",s);
- X break;
- X case '\f':
- X printf ("<formfeed> - %s\n",s);
- X break;
- X case '\07':
- X printf (" <bell> - %s\n",s);
- X break;
- X case '\0':
- X printf (" <null> - %s\n",s);
- X break;
- X default:
- X if (c < '\033')
- X {
- X c += 'a' - 1;
- X printf(" control-%c - %s\n",c,s);
- X }
- X else
- X printf(" %c0%o - %s\n",'\\',(int) c,s);
- X break;
- X }
- X }
- X}
- X
- Xtot_list (rec,hirec)
- Xint *rec;
- Xint *hirec;
- X{
- X int i,max,len;
- X char c;
- X char ff[MAX_C+1];
- X
- X term_set (ERASE);
- X
- X for (max=i=0; i < Ncount; ++i)
- X {
- X if ((Newsorder[i])->pages == 0)
- X continue;
- X if ((len = strlen((Newsorder[i])->nd_name)) > max)
- X max = len;
- X }
- X
- X sprintf (ff,"%%4d %%%ds: %%3d new %%3d updated\n",max);
- X
- X for (len=i=0; i < Ncount; ++i)
- X {
- X if ((Newsorder[i])->pages == 0)
- X continue;
- X printf (ff, i, (Newsorder[i])->nd_name,
- X (Newsorder[i])->art - (Newsorder[i])->orgrd,
- X (Newsorder[i])->rdnum - (Newsorder[i])->orgrd);
- X ++len;
- X if (len == L_allow && i < (Ncount-1))
- X {
- X printf("\nr - return, n - new group, other to continue ... ");
- X if ((c = getnoctl()) == 'r' || c == 'n')
- X break;
- X printf ("\n\n");
- X len = 0;
- X }
- X }
- X if (i >= Ncount)
- X {
- X printf("n - new group, other to return ... ");
- X c = getnoctl();
- X }
- X if (c == 'n')
- X {
- X printf("\n");
- X user_str(ff,"Newsgroup number ? ",0);
- X i = atoi(ff);
- X if (i < 0)
- X i = 0;
- X if (i >= Ncount)
- X i = Ncount-1;
- X find_page((Newsorder[i])->pnum);
- X *rec = RECBIAS;
- X *hirec = Page.h.artnum + RECBIAS;
- X }
- X}
- @//E*O*F vn.c//
- if test 25993 -ne "`wc -c <'vn.c'`"; then
- echo shar: error transmitting "'vn.c'" '(should have been 25993 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'vn.man'" '(19673 characters)'
- if test -f 'vn.man' ; then
- echo shar: will not over-write existing file "'vn.man'"
- else
- sed 's/^X//' >vn.man <<'@//E*O*F vn.man//'
- X.TH VN 1 2/1/85
- X.UC
- X.SH NAME
- Xvn - visual news reader
- X.SH SYNOPSIS
- X.I vn
- X.SH DESCRIPTION
- X.I Vn
- Xis a news reader which uses the same
- X.B .newsrc
- Xfile as
- X.I readnews
- X(1), but displays and interacts differently. It is aimed at allowing
- Xyou to rapidly scan a large number of newsgroups, looking for something
- Xyou want to read. The major premise is that you will be interested in a
- Xsmall number of articles, but will be interested in keeping tabs on a large
- Xnumber of newsgroups which may contain something interesting from time to time.
- XIt also has the ability to unpackage digests.
- X.sp
- X.I Vn
- Xsupports the -n, -x and -t options of
- X.I readnews
- X(newsgroup, read all articles, and title). In addition, there
- Xis a -w (writer) option which works like -t, but is a search string to
- Xapply to the "From" header line rather than the subject. In the -n, -t
- Xand -w options, a leading ! on the string is taken to mean negation.
- XThe rest of the string is a regular expression for the -w and -t options.
- X.sp
- XFor example:
- X.sp
- X-n net.dogs -w !fred -t [Bb]eagle
- X.sp
- XFor articles in net.dogs about beagles written by somebody other
- Xthan fred. Multiple -w -t options are treated as follows:
- X.in +5
- X.sp
- XIf the article satisfies any of the negations, you won't see it,
- Xregardless of the non-negated options.
- X.sp
- XMultiple -w options are logically "or'ed", as are multiple -t's.
- X.sp
- XIf both -w and -t are present, the article is seen only if it satisfies
- Xat least one of the -w's and at least one of the -t's, ie. the results of the
- Xlogical "or's" of the -t's and -w's are logically "anded".
- X.sp
- X.in -5
- XThe -n options allow the "all" convention, replacing ".all" by
- X".*" before using the regular expression calls. -n options are processed
- Xin order given, so that subsequent more specific -n's may partially
- Xundo the effect of previous "alls". Note that the -n option
- Xtreatment is slightly different than the
- X.I readnews
- Xtreatment which says that "foo" implies "foo.all".
- X.I Vn
- Xaccepts this incompatibility to allow you an easier way of saying JUST "foo"
- Xwithout any of its subgroups.
- X.sp
- XOptions may be given on the command line, in which case they will
- Xsupersede those given in the
- X.B .newsrc
- Xfile. For command line -n options, the "!" unsubscriptions in
- X.B .newsrc
- Xare also ignored. This allows you to override all subscription information
- Xby command line specification. If you use an -S option on the command line,
- Xthe "!" unsubscriptions will still be used. -S is meaningless in the
- X.B .newsrc
- Xfile.
- X.sp
- XThere are three more options specific to
- X.I vn:
- Xthe -% and -U. The -% option initially gives you the results of a "%"
- Xcommand, rather than the page for the first newsgroup (see below).
- XThis allows you to see what newsgroups are available before viewing any.
- XThe -U option says that when your
- X.B .newsrc
- Xfile is updated via answering "yes" to the update query on
- Xexit or using control-W, newsgroups marked with "!" are to be updated too.
- XNormally, these groups are left alone, ie. updated only to the number that
- Xwas already in your
- X.B .newsrc,
- Xor the lowest article number still around.
- XYou may get flooded should you decide to resubscribe.
- XIf you don't like this treatment, use -U. Then, control-W and "yes" to
- Xthe update on exit will update your unsubscribed newsgroups to the most
- Xrecent article.
- X.sp
- XWhen
- X.I vn
- Xis invoked,
- Xthere will be a pause (with an explanatory "reading" message and
- Xa series of newsgroups) while vn reads the news. The newsgroups listed
- Xare ones articles are actually being found in.
- XThe length of the pause depends
- Xon how much news there is. If there is a lot,
- Xit may take a long time to get through the reading phase.
- X.sp
- XOnce the reading phase is over, interaction is rapid.
- XIf
- X.I vn
- Xis backgrounded, it suppresses the "reading" output, so
- Xthat it will not halt on tty output until it is ready to begin showing
- Xarticles.
- X.sp
- X.I Vn
- Xmay show you a list of newsgroups which were not mentioned in the
- X.B .newsrc
- Xfile. Records for these newsgroups will be added, whether
- Xthey were scanned for articles or not. The first time
- X.I vn
- Xis used, the list may be quite long and scroll off the screen.
- XThereafter, there should only be a list when new newsgroups are
- Xcreated. This display serves to let you know of their existence,
- Xor of something happening to your
- X.B .newsrc
- Xfile.
- X.sp
- XThe basic display is a "page" which shows a newsgroup and a list of
- Xtitles, number of
- Xlines, and authors for new articles.
- XArticles which have been updated in the
- X.B .newsrc
- Xfile are flagged with an underscore preceding the article number.
- XYou also have the ability to "mark" articles for the duration of a session,
- Xshown with an asterisk (col. 1 and 2 are reserved for asterisk and
- Xunderscore respectively -
- Xin normal usage they will be blank, so that the casual user will probably
- Xbe unaware of their use until marking and updating are invoked)
- X.sp
- XThere is a help menu to go with this page.
- XYou may read articles, save them, send them to the printer, either by cursor
- Xposition, the whole page, or in specified sets. Sets are specified either
- Xas a set of article numbers, a regular expression to match the subject /
- Xauthor / number of lines data on, or an asterisk to indicate the choice
- Xof a set of previously marked articles. Any of these methods also
- Xaccept a leading "!" to indicate negation.
- X.sp
- XBy default, when you read articles only a couple of the dozen or so
- Xheader lines are
- Xshown. There is an option to allow you to see all the
- Xheader lines when you read articles. The command controlling this toggles
- Xbetween the two states.
- X.sp
- XA similar toggle is used to support ROT13.
- X.sp
- X.I Vn
- Xis capable of manipulating digests. The "d" command unpacks a digest,
- Xand presents you with a page showing the unpacked articles, which can
- Xbe accessed as for articles on normal newsgroup pages.
- XWhen you leave the digest page(s), you reenter the normal flow of newsgroups.
- XDigests can also be read as normal articles, of course.
- X.sp
- XOrder of pages is determined by
- Xorder of groups in
- X.B .newsrc.
- XNewsgroups which are not
- Xmentioned in
- X.B .newsrc
- Xwill be added, as mentioned previously, and tacked onto the end.
- XLines corresponding to non-existent newsgroups will be deleted.
- XYou will probably want to run
- X.I vn
- Xonce, then edit
- X.B .newsrc
- Xto the desired order of presentation.
- X.sp
- XUpdating the data for
- X.B .newsrc
- Xis under user control. If you do
- Xno "W", "w", "^w", o or O commands, no updating takes place, and you'll see the
- Xarticles again the next time you read news.
- XIf you quit without updating, you will be prompted to make sure you
- Xdon't want to do so.
- X.sp
- XNote that "updating what you've seen" to
- X.I vn
- Xmeans that you've seen the page presentation, not that you've read the
- Xarticle. This is consistent with the overall assumption that you don't
- Xwant to read most of what you are presented with.
- X.sp
- XBreaks result in a "really quit?" query, so you can recover from noisy
- Xlines and prompts for commands you didn't really mean. If you answer no,
- Xyou are simply jumped back to the page. Breaks while in the midst of scrolling
- Xout an article you are reading jump you to the end of the article to stop
- Xthe output.
- X.sp
- XCommands are single character (no return key required), except that
- Xthey may be preceded with numeric characters, which may have
- Xsome effect on their actions. Commands which require further input
- Xcause prompts for the information, this input being
- Xterminated by return. For prompted input, the erase and kill keys
- Xwork.
- X.sp
- X.ce 1
- XCommand Menu For Page:
- X.sp
- X.nf
- X[...] = effect of optional number preceding command
- Xpipes are specified by filenames beginning with |
- Xarticles specified as a list of numbers, title search string, or
- X * to specify marked articles. ! may be used to negate any
- X
- X q - quit
- X k - (or up arrow) move up [number of lines]
- X j - (or down arrow) move down [number of lines]
- X <back sp> - (or left arrow) previous page [number of pages]
- X <return> - (or right arrow) next page [number of pages]
- X d - unpack digest
- X r - read article [number of articles]
- X <space> - read article (alternate 'r')
- X R - read all articles on page
- X control-r - specify articles to read
- X s - save or pipe article [number of articles]
- X S - save or pipe all articles on page
- X control-s - specify articles to save
- X control-t - specify articles to save (alternate ctl-s)
- X p - print article [number of articles]
- X P - print all article on page
- X control-p - specify articles to print
- X w - update .newsrc status to cursor
- X W - update .newsrc status for whole newsgroup
- X control-w - update .newsrc status for all pages displayed
- X o - recover original .newsrc status for newsgroup
- X O - recover all original .newsrc status
- X # - display count of groups and pages - shown and total
- X % - list newsgroups with new article, updated counts
- X n - specify newsgroup to display and/or resubscribe to
- X u - unsubscribe from group
- X x - mark/unmark article [number of articles]
- X * - mark/unmark article [number of articles]
- X X - erase marks on articles
- X h - toggle flag for display of headers when reading
- X z - toggle rotation for reading
- X<formfeed> - redraw screen
- X ! - escape to UNIX to execute a command
- X ? - show this help menu
- X.fi
- X.sp
- XWhen you read articles, there is another help menu, for advancing through
- Xthe articles, replying, posting followups, and saving the
- Xarticles. Breaks may be used to
- Xstop the output of an article if you decide that you didn't really
- Xwant to read it. You can jump from the reading portion back to either
- Xpage you came from or the NEXT page.
- X.sp
- XFor replying and posting followups, you will be thrown into an editor
- Xto create the reply or article.
- XThe article will be included in the file you are editing, marked with
- X"> "'s for excerpting in your reply or followup. After you exit the
- Xeditor, you are prompted to make sure you still want to post or reply,
- Xso you can abort.
- X.sp
- XFor followups, your article is appended to "author_copy" for future
- Xreference.
- X.sp
- XHeader lines for the mailer / news poster are present in the file
- Xyou are editing to allow you to modify them. Remember to leave a blank
- Xline between the header lines and your text. It may be OK if you
- Xdon't, but why tempt fate.
- X.sp
- XThe editor is determined by your EDITOR variable, as for
- X.I postnews.
- XIf EDITOR is not set, you get
- X.I vi,
- Xor the default determined at your site.
- X.sp
- X.ce 1
- XReading menu:
- X.sp
- X.nf
- X n - next article, if any
- X q - quit reading articles, if any more to read
- X Q - quit reading, and turn to next page of articles
- X r - rewind article to beginning
- X <return> - next line
- X / - search for a pattern in the article
- X m - send mail to author of article
- X f - post followup to article
- X s - save article in a file
- X p - send article to the printer
- X ? - see this help menu
- X z - toggle rotation flag
- X h - toggle header suppression flag
- X
- X anything else to continue normal reading
- X.fi
- X.sp
- XIf you don't like the choice of command keys, you
- Xmay change them (default choices - basic control in article
- Xreader is ala "more" of course, the "j" and "k" on the page presentation
- Xare "vi" convention, other page commands are somewhat "readnews" compatible).
- XIf you have a file named
- X.B .vnkey
- Xin your home directory this file will be read in order to obtain keystroke
- Xtranslation. The format is simple:
- X.sp
- XEach line begins with R or P indicating translation for the reader interaction,
- Xor the page interaction (r and p accepted also). Following the R or P is
- Xa character, followed by an "=", followed by another character. The character
- Xon the left hand side of the equals sign is what you wish to input, and the
- Xcharacter on the right hand side of the equals sign is what you wish to
- Xtranslate it to. No embedded spaces.
- XLines not beginining with the proper characters are simply
- Xignored, as are characters following the translated character. Eg:
- X.sp
- X.in +5
- XPd=j
- X.br
- XPu=k
- X.in -5
- X.sp
- Xuses "u" and "d" instead of "j" and "k" on the page layout (presumably,
- Xyou are also going to translate something else to "u" and "d" for the
- Xunsubscribe and digest commands). If you translate keys, it is up to you
- Xto see that all commands can still be reached, and that former command keys
- Xwhich are no longer used are mapped to something meaningless. In particular,
- Xyou are going to have difficulties if you make it impossible to input "q". The
- Xhelp menus will show the "new" keys, and bad mappings should show up as
- Xmultiple definitions for the same key, or alternate mappings not showing
- Xup on the help menu.
- X.sp
- XMapping the "=" key via "==" works. Any keys not mentioned in the file
- Xare translated to themselves.
- X.sp
- XControl keys are given as DECIMAL numbers with no backslashes or anything.
- XThe decimal number is the ASCII code for the character, eg:
- X.sp
- X.in +5
- XP24=12
- X.br
- XP12=?
- X.in -5
- Xuses "control-x" for the "control-l (formfeed)" refresh key, and maps the
- Xcontrol-l to a "?". BTW, mapping all undefined keys to "?" will mean that you
- Xautomatically get the help display for any illegal key, should you wish for
- Xsuch a thing. The LAST one mapped will determine what key is given in
- Xthe "? for help" lines, and the help display itself.
- XRemembering that control-A through
- Xcontrol-Z are ASCII codes 1 through 26 and delete = 127 may keep you from
- Xhaving to consult an ASCII table. Remember also that some controls, such
- Xas control- C, Z, S or Q may be caught by the operating system for signal
- Xgeneration or terminal control, and are thus unavailable.
- X.sp
- XBecause of arrow keys and the ability to prefix commands with counts,
- Xnumeric characters and the escape key may not be used for page commands.
- XAttempts to use them will simply do nothing.
- X.sp
- XControl keys are not available for the reader, except for newline,
- Xbackspace, and tab. The reason controls are filtered here has to do
- Xwith nasty problems involving terminal mode switches on some systems,
- Xspecifically a UTS frontend early versions were being used on.
- X.sp
- XIn either interaction, "return" and "linefeed" are mapped to the "newline"
- Xcharacter at a level below the translation. If you don't know the
- XASCII for the "newline" char, it is recommended that you map both
- XASCII 10 and 13 if you wish to map "return" to something.
- X.SH FILES
- X.TP 24
- X/usr/tmp/*
- XOne temporary file created by
- X.I tmpnam
- X(3), and immediately unlinked,
- Xremains open in update mode for duration of session.
- XDisk space freed by system close of file descriptor at exit.
- XCan be large, as this file contains the "page" displays.
- XTemporary files also created by
- X.I tmpnam
- X(3) for mailing replies, posting followups and creating digest "articles".
- X.TP 24
- X(login directory)/.newsrc
- Xnews status file. Updated following session. See NEWSRC environment variable.
- X.TP 24
- X(login directory)/author_copy
- XA copy of all articles posted using the followup command will be appended
- Xto this file in /bin/mail format. See CCFILE environment variable.
- X.TP 24
- X(login directory)/.vnkey
- XKeystroke mapping file for changing command characters.
- X.TP 24
- X(login directory)/*.vnXXXXXX
- XOne temporary file created by
- X.I tmpnam
- X(3) while updating the .newsrc file. If the update fails, you are informed,
- Xand this file
- Xmay be used to recover the last update. Unlinked following successful update.
- X.TP 24
- X(spool directory)/*
- Xspooling directories containing articles.
- X.TP 24
- X/usr/lib/news/active
- Xactive newsgroup list.
- X.SH "ENVIRONMENT VARIABLES"
- X.TP 24
- XPS1
- Xused to present prompt string for command on unix escape.
- Xdefaults to "$ "
- X.TP 24
- XEDITOR
- Xeditor used for mailing replies and posting followups.
- Xdefaults to "ed".
- X.TP 24
- XPOSTER
- Xposting program for followups. defaults to "inews -h".
- X.TP 24
- XMAILER
- Xused when mailing replies. defaults to "sendmail -t".
- X.TP 24
- XPRINTER
- Xprogram used with the print commands for sending articles to
- Xthe printer. defaults to "lpr".
- X.TP 24
- XNEWSRC
- Xif set, can be used to override the choice of ".newsrc" as the
- Xname for the status file. Name will still be used relative to
- Xthe login directory, unless it begins with "/".
- X.TP 24
- XCCFILE
- Xif set, overrides the choice of "author_copy" as the name of the
- Xfile to CC all articles posted with the followup command. Name
- Xwill still be used relative to the login directory, unless it begins
- Xwith "/".
- X.TP 24
- XVNKEY
- Xif set, overrides the choice of ".vnkey" as the name of the
- Xfile to map keys from. Name
- Xwill still be used relative to the login directory, unless it begins
- Xwith "/".
- X.SH DIAGNOSTICS
- Xuser error messages. self explanatory.
- X.SH AUTHOR
- XR. L. McQueer
- X.SH BUGS
- XNote that
- X.I readnews
- Xwill rearrange the order of
- X.B .newsrc.
- XIf you
- Xinterleave use of it with
- X.I vn,
- Xorder selection gets hosed.
- X.sp
- XIf you've really taken advantage of the ability of readnews to skip
- Xarticles in the middle of the spooling numbers, be warned that
- X.I vn
- Xdoesn't have it, and will
- Xassume you've read the articles in the middle.
- X.sp
- XIf the
- X.B .newsrc
- Xfile indicates that you've read articles in a newsgroup with a higher
- Xnumber than the current spooling number for that newsgroup,
- X.I vn
- Xwill show you the entire newsgroup. This is intended for recovery in
- Xcases where article spooling has been reset, or to avoid missing articles
- Xbecause you just changed machines and didn't bother to edit your
- X.B .newsrc
- Xfile. Rather than miss stuff, you'll see some old stuff again.
- X.sp
- XSometimes a "break" during reading an article will not only halt the
- Xarticle but suppress the prompt. A command character will work anyway.
- X.sp
- XIf a prompt to be displayed on the dialogue line
- Xcontains non-printing sequences, stuff on the
- Xline may not get erased when you are prompted, because
- X.I vn
- Xthinks the string is long enough to overprint its current contents.
- XThis usually comes up when you have escape sequences in your UNIX
- Xprompt, and do a "!" command.
- XThe "overprint" check is made to save a clear-line sequence (kludged in
- Xby overprinting to the end with blanks if the terminal doesn't
- Xhave one - annoying at 1200 baud).
- X.sp
- XOutput during the reading phase which was suppressed by backgrounding
- X.I vn
- Xdoes not get started by foregrounding it again without doing a
- Xcontrol-z and a second foreground (it doesn't figure out its background /
- Xforeground status on each output - only on startup and while handling
- Xthe SIGTSTP signal). Actually, this results in a method for having
- X.I vn
- Xdo its reading phase silently in the foreground without redirecting
- Xoutput, should such a thing be desired.
- X.sp
- XVery many -w or -t options cause SLOW reading phases. It is reccomended
- Xthat these be used only when reading a few specific groups.
- X.sp
- XDigest extraction will split a single article into several if it contains
- Xembedded ---- lines, the normal separator between articles in digests.
- XThey will all have identical titles.
- XDigest extraction may not work with human built digests which don't
- Xuse the expected syntax for joining articles. mod.computers.ibm-pc
- Xand mod.computers.mac were used as models for the feature.
- X.sp
- XThe data given by the % command represents the difference between the
- Xlast article number you've updated to in a newsgroup and the high
- Xarticle number. This may be significantly greater than the number of
- Xactual articles for a newsgroup you haven't been reading, and for
- Xnewsgroups that have had a lot of articles filtered out of them using
- Xthe -w and -t options. The numbers given for menu selection in the
- X % command are the order numbers from the .newsrc, and have gaps for
- Xunsubscribed newsgroups.
- X.sp
- XThe key mapping capability doesn't handle function keys. Because of the
- Xuse of controls as commands, terminals whose arrow keys echo something
- Xother than a sequence beginning with escape can't use arrow keys. For
- Xthese terminals, a warning message is printed during the reading phase.
- @//E*O*F vn.man//
- if test 19673 -ne "`wc -c <'vn.man'`"; then
- echo shar: error transmitting "'vn.man'" '(should have been 19673 characters)'
- fi
- fi # end of overwriting check
- echo shar: "End of archive 3 (of 3)."
- cp /dev/null ark3isdone
- DONE=true
- for I in 1 2 3; do
- if test -! f ark${I}isdone; then
- echo "You still need to run archive ${I}."
- DONE=false
- fi
- done
- case $DONE in
- true)
- echo "You have run all 3 archives."
- echo 'Now read the README'
- ;;
- esac
- ## End of shell archive.
- exit 0
-